#pragma once
#include <memory>
#include <string>
#include <mutex>
#include <future>
#include <map>
#include <condition_variable>
#include <vector>
#include <functional>
#include "json.h"
#include "HidDevice.h"

#define HID_DEVICE_PREFIX_NAME "/dev/hidraw"

typedef struct{
    std::string m_product_name;
    std::string m_product_model; 
    std::string m_phy_version; 
    std::string m_soft_version; 
    std::string m_serial_number; 
    std::string m_unique_id;
    std::vector<HidDevInfo> m_sub_devices;
}HidDeviceInfo;

class HidDeviceManager{
public:
    using Ptr = std::shared_ptr<HidDeviceManager>;

    static Ptr Instance();
    HidDeviceManager();
    ~HidDeviceManager();

    std::vector<HidDeviceInfo> GetHidDeviceList();
    bool Upgrade(const std::string& serial_number, const std::string& upgrade_file, 
        std::function<void (const std::string, int)> notifyProgress);
    
    bool Reboot(const std::string& serial_number);
    bool Reset(const std::string& serial_number);
private:
    void deviceCheck();
    void updateUpgradeProgress(const std::string& serial_number, const std::string& product_name, int progress);
    bool getCmdInfo(char *cmd, std::vector<std::string> &info);

    std::recursive_mutex m_mux;
    std::map<std::string, HidDevice::Ptr> m_devices;
    std::future<void> m_checkDeviceTask;
    std::condition_variable m_cv;
    std::mutex m_cv_mux;

};
